package com.smy.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smy.reggie.common.R;
import com.smy.reggie.dto.DishDto;
import com.smy.reggie.pojo.Category;
import com.smy.reggie.pojo.Dish;
import com.smy.reggie.pojo.DishFlavor;
import com.smy.reggie.service.CategoryService;
import com.smy.reggie.service.DishFlavorService;
import com.smy.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 双表添加
     * @param dto
     * @return
     */
    @PostMapping
    public R<String> addDishAndFlavor(@RequestBody DishDto dto){
        dishService.saveWithFlavor(dto);
        //删除该菜品所在分类的缓存数据
        String key = "dish_" + dto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return R.success("添加成功");
    }

    /**
     * 分页查询菜品和分类
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    private R<Page<DishDto>> selectByPage(Long page,Long pageSize,String name){
        Page<Dish> dishPage = new Page<>(page,pageSize);
        Page<DishDto> dishDtoPage = new Page<>();
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Dish::getUpdateTime);
        wrapper.like(name != null,Dish::getName,name);
        dishService.page(dishPage,wrapper);
        BeanUtils.copyProperties(dishPage,dishDtoPage);
        List<Dish> records = dishPage.getRecords();
        List<DishDto> dishDtoList = records.stream().map((item)->{
            Long id = item.getCategoryId();
            Category category = categoryService.getById(id);
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            dishDto.setCategoryName(category.getName());
            return dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(dishDtoList);
        return R.success(dishDtoPage);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    private R<DishDto> selectById(@PathVariable Long id){
        return R.success(dishService.selectWithFlavor(id));
    }

    /**
     * 双表修改
     * @param dto
     * @return
     */
    @PutMapping
    private R<String> update(@RequestBody DishDto dto){
        dishService.updateWithFlavor(dto);
        //删除该菜品所在分类的缓存数据
        String key = "dish_" + dto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return R.success("修改成功！");
    }

    /**
     * 批量修改状态
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    private R<String> updateStatus(@PathVariable Integer status,@RequestParam Long[] ids){
        Dish dish = new Dish();
        dish.setStatus(status);
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Dish::getId,ids);
        log.warn(dish.getStatus().toString());
        dishService.update(dish,wrapper);
        return R.success("状态更改完成！");
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @DeleteMapping
    private R<String> delete(@RequestParam Long[] ids){
        List<Long> ids2 = Arrays.asList(ids);
        //根据ids分别获取该菜品所在分类
        for (Long id : ids) {
            Dish byId = dishService.getById(id);
            //删除该菜品所在分类的缓存数据
            String key = "dish_" + byId.getCategoryId() + "_1";
            redisTemplate.delete(key);
        }
        dishService.removeByIds(ids2);

        return R.success("删除成功！");
    }

    /**
     * 条件查询多条数据 , 返回集合
     * @param dishDto
     * @return
     */
    @GetMapping("/list")
    private R<List<DishDto>> getByCondition(DishDto dishDto){
        //声明最终返回对象
        List<DishDto> dtoList = null;
        //动态获取该次查询前端传输数据拼接字符串
        String key = "dish_"+dishDto.getCategoryId() + "_" + dishDto.getStatus();
        //查看缓存中是否拥有对象
        dtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        //拥有则直接返回
        if (dtoList != null){
            return R.success(dtoList);
        }

        //未拥有则执行查询后将数据存入缓存

        //创建查询对象
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        //根据分类Id查询
        wrapper.eq(dishDto.getCategoryId() != null,Dish::getCategoryId,dishDto.getCategoryId());
        //根据修改时间排序
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        //状态为在售
        wrapper.eq(Dish::getStatus,1);
        //创建List对象接收查询返回结果
        List<Dish> list = dishService.list(wrapper);
        //转变为Dto对象
        dtoList = list.stream().map((item)->{
            //获取每项Id
            Long dishId = item.getId();
            //创建查询对象
            LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
            //根据Id查询对象
            dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);
            //创建List对象接收查询返回结果
            List<DishFlavor> flavor = dishFlavorService.list(dishFlavorLambdaQueryWrapper);

            //获取分类Id
            Long id = item.getCategoryId();
            //根据分类Id获取分类对象
            Category category = categoryService.getById(id);

            //创建Dto对象
            DishDto newDishDto = new DishDto();
            //使用对象拷贝工具将原对象拷贝到Dto里
            BeanUtils.copyProperties(item,newDishDto);

            //在Dto中填充对应数据
            newDishDto.setCategoryName(category.getName());
            newDishDto.setFlavors(flavor);

            //返回Dto对象
            return newDishDto;
        }).collect(Collectors.toList());
        //将数据存入缓存
        redisTemplate.opsForValue().set(key,dtoList,30, TimeUnit.MINUTES);
        return R.success(dtoList);
    }
}
